home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 24 / CU Amiga Magazine's Super CD-ROM 24 (1998)(EMAP Images)(GB)(Track 1 of 2)[!][issue 1998-07].iso / CUCD / Programming / SWI / source / src / pl-term.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-02-18  |  5.3 KB  |  237 lines

  1. /*  $Id: pl-term.c,v 1.15 1998/02/18 13:57:23 jan Exp $
  2.  
  3.     Copyright (c) 1990 Jan Wielemaker. All rights reserved.
  4.     See ../LICENCE to find out about your rights.
  5.     jan@swi.psy.uva.nl
  6.  
  7.     Purpose: Simple terminal handling
  8. */
  9.  
  10. #include "pl-incl.h"
  11.  
  12. /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  13. This module defines some hacks to get to the unix  termcap  library.   I
  14. realise this is not a proper answer to terminal control from Prolog, but
  15. I  needed  it  some day and at least it is better than doing things like
  16. shell(clear), coding terminal sequences hard, etc.   One  day  I  should
  17. write a decent interface to handle the terminal.  Maybe this will be too
  18. late;  character terminals  disappear quickly now.  Use XPCE if you want
  19. windowing!
  20. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  21.  
  22. #ifdef HAVE_TGETENT
  23. extern int  tgetent();
  24. extern int  tgetnum();
  25. extern int  tgetflag();
  26. extern char *tgetstr();
  27. extern char *tgoto();
  28. extern int  tputs();
  29.  
  30. #define MAX_TERMBUF    1024        /* Confirming manual */
  31. #define STAT_START    0
  32. #define STAT_OK        1
  33. #define STAT_ERROR    2
  34.  
  35. extern int Output;            /* Current output stream */
  36. char    PC;                /* Term lib variables */
  37. char   *BC;
  38. char   *UP;
  39. short    ospeed;
  40.  
  41. static int    term_initialised;    /* Extracted term info? */
  42. static char     *string_area_pointer;    /* Current location */
  43. static Table    capabilities;        /* Terminal capabilities */
  44. static atom_t    tty_stream;        /* stream on which to do tty */
  45.  
  46. typedef struct
  47. { atom_t type;                /* type of the entry */
  48.   atom_t name;                /* Name of the value */
  49.   word  value;                /* Value of the entry */
  50. } entry, *Entry;
  51.  
  52. forwards bool    initTerm(void);
  53. forwards Entry    lookupEntry(atom_t, atom_t);
  54.  
  55. void
  56. resetTerm()
  57. { if ( capabilities == NULL )
  58.   { capabilities = newHTable(16);
  59.   } else
  60.   { Symbol s;
  61.  
  62.     term_initialised = STAT_START;
  63.     for_table(s, capabilities)
  64.       freeHeap(s->value, sizeof(entry));
  65.     clearHTable(capabilities);
  66.   }
  67.  
  68.   tty_stream = ATOM_user_output;
  69. }
  70.  
  71. static bool
  72. initTerm(void)
  73. { static char *buf = NULL;
  74.   static char *string_area = NULL;
  75.  
  76.   if ( term_initialised == STAT_START )
  77.   { char term[100];
  78.  
  79.     term_initialised = STAT_ERROR;
  80.     if ( !getenv3("TERM", term, sizeof(term)) )
  81.       return warning("No variable TERM");
  82.  
  83.     if ( buf == NULL )         buf         = allocHeap(MAX_TERMBUF);
  84.     if ( string_area == NULL ) string_area = allocHeap(MAX_TERMBUF);
  85.     string_area_pointer = string_area;
  86.  
  87.     switch( tgetent(buf, term) )
  88.     { case -1:    return warning("Cannot open termcap file");
  89.       case  1:    break;
  90.       default:
  91.       case  0:    return warning("Unknown terminal: %s", term);
  92.     }
  93.  
  94.     term_initialised = STAT_OK;
  95.   }
  96.  
  97.   return term_initialised == STAT_OK;
  98. }
  99.  
  100. static Entry
  101. lookupEntry(atom_t name, atom_t type)
  102. { Symbol s;
  103.   Entry e;
  104.  
  105.   if ( (s = lookupHTable(capabilities, (void*)name)) == NULL )
  106.   { if ( initTerm() == FALSE )
  107.       return NULL;
  108.  
  109.     e = (Entry) allocHeap(sizeof(entry));
  110.     e->name = name;
  111.     e->type = type;
  112.     e->value = 0L;
  113.  
  114.     if ( type == ATOM_number )
  115.     { int n;
  116.  
  117.       if ( (n = tgetnum(stringAtom(name))) != -1 )
  118.         e->value  = consInt(n);
  119.     } else if ( type == ATOM_bool )
  120.     { bool b;
  121.     
  122.       if ( (b = tgetflag(stringAtom(name))) != -1 )
  123.         e->value = (b ? ATOM_on : ATOM_off);
  124.     } else if ( type == ATOM_string )
  125.     { char *s;
  126.     
  127.       if ( (s = tgetstr(stringAtom(name), &string_area_pointer)) != NULL )
  128.         e->value  = lookupAtom(s);
  129.     } else
  130.     { warning("tgetent/3: Illegal type");
  131.       freeHeap(e, sizeof(entry));
  132.       return NULL;
  133.     }
  134.  
  135.     addHTable(capabilities, (void *)name, e);
  136.     return e;
  137.   } else
  138.     return (Entry) s->value;
  139. }
  140.       
  141. word
  142. pl_tty_get_capability(term_t name, term_t type, term_t value)
  143. { Entry e;
  144.   atom_t n, t;
  145.  
  146.   if ( !PL_get_atom(name, &n) || !PL_get_atom(type, &t) )
  147.     return warning("tgetent/3: instantiation fault");
  148.   if ( !(e = lookupEntry(n, t)) )
  149.     fail;
  150.  
  151.   if ( e->value != 0L )
  152.     return _PL_unify_atomic(value, e->value);
  153.  
  154.   fail;
  155. }
  156.   
  157. word
  158. pl_tty_goto(term_t x, term_t y)
  159. { Entry e;
  160.   char *s;
  161.   int ix, iy;
  162.   term_t ttys = PL_new_term_ref();
  163.  
  164.   if ( !PL_get_integer(x, &ix) ||
  165.        !PL_get_integer(y, &iy) )
  166.     return warning("tty_goto: instantiation fault");
  167.  
  168.   if ( (e = lookupEntry(ATOM_cm, ATOM_string)) == NULL ||
  169.         e->value == 0L )
  170.     fail;
  171.  
  172.   s = tgoto(stringAtom(e->value), ix, iy);
  173.   if ( streq(s, "OOPS") )
  174.     fail;
  175.  
  176.   PL_put_atom(ttys, tty_stream);
  177.   streamOutput(ttys, (tputs(s, 1, Put), TRUE));
  178. }
  179.  
  180. word
  181. pl_tty_put(term_t a, term_t affcnt)
  182. { char *s;
  183.   int n;
  184.  
  185.   if ( PL_get_chars(a, &s, CVT_ALL) &&
  186.        PL_get_integer(affcnt, &n) )
  187.   { term_t ttys = PL_new_term_ref();
  188.     PL_put_atom(ttys, tty_stream);
  189.  
  190.     streamOutput(ttys, (tputs(s, n, Put), TRUE));
  191.   }
  192.  
  193.   return warning("tty_put: instantiation fault");
  194. }
  195.  
  196. word
  197. pl_set_tty(term_t old, term_t new)
  198. { atom_t a;
  199.  
  200.   if ( PL_unify_atom(old, tty_stream) &&
  201.        PL_get_atom(new, &a) &&
  202.        streamNo(new, F_WRITE) >= 0 )
  203.   { tty_stream = a;
  204.     succeed;
  205.   }
  206.  
  207.   fail;
  208. }
  209.  
  210. #else /* ~TGETENT */
  211.  
  212. void resetTerm()
  213. {
  214. }
  215.  
  216. word
  217. pl_tty_get_capability(term_t name, term_t type, term_t value)
  218. { return notImplemented("tty_get_capability", 3);
  219. }
  220.  
  221. word
  222. pl_tty_goto(term_t x, term_t y)
  223. { return notImplemented("tty_goto", 2);
  224. }
  225.  
  226. word
  227. pl_tty_put(term_t a, term_t affcnt)
  228. { return notImplemented("tty_put", 2);
  229. }
  230.  
  231. word
  232. pl_set_tty(term_t old, term_t new)
  233. { return notImplemented("set_tty", 2);
  234. }
  235.  
  236. #endif /* TGETENT */
  237.